﻿namespace Guru.Framework.Management
{
    using Guru.Framework.Base;
    using Guru.Framework.DBConnection;
    using Guru.Framework.QueryBuilding;
    using System;
    using System.Collections;
    using System.Data;

    /// <summary>
    /// General Database Manager for Database Operations.
    /// </summary>
    public class DbManager : IDbManager
    {
        #region [ protected fields ]

        protected IConnection Conn = null;

        #endregion

        #region [ private fields ]

        private string _ConnStr;
        private ConnectionTypes _ConType;

        #endregion

        #region [ DbManager Constructor with ConnectionType. ]

        /// <summary>
        /// DbManager Constructor  with Empty Connection string.
        /// </summary>
        /// <param name="ConnType">Connection Type</param>
        public DbManager(ConnectionTypes ConnType)
            : this(ConnType, string.Empty)
        { }

        #endregion


        #region [ DbManager Constructor  with Connection Type and Connection string. ]

        /// <summary>
        /// DbManager Constructor
        /// </summary>
        /// <param name="ConnType">Connection Type</param>
        /// <param name="ConnectionString">Connection String</param>
        public DbManager(ConnectionTypes ConnType, String ConnectionString)
        {
            _ConnStr = ConnectionString;
            _ConType = ConnType;

            Conn = new Connection(_ConType, _ConnStr);
        }

        #endregion


        #region [ ConnectionString Property. ]

        /// <summary>
        /// Gets And Sets Connection String of Manager.
        /// </summary>       
        public String ConnectionString
        {
            set
            {
                _ConnStr = value;
            }
            get
            {
                return "";
            }
        }

        #endregion


        #region [ ConnectionType Property. ]

        /// <summary>
        /// Gets Connection Type Of Manager.
        /// </summary>
        public ConnectionTypes ConnectionType
        {
            get
            { return _ConType; }
        }

        #endregion


        #region [ CreateQueryBuilder method. ]

        /// <summary>
        /// Create A QueryBuilder object with ConnectionType Of Connection and given querytype and AbstractBaseBo object.
        /// </summary>
        /// <param name="queryType">QueryType Of QueryBuilder</param>
        /// <param name="tableObject">Table class object.</param>
        /// <returns>Returns A QueryBuilder object with ConnectionType Of Connection and given querytype and AbstractBaseBo object.</returns>
        public QueryBuilder CreateQueryBuilder(QueryTypes queryType, AbstractBaseBO tableObject)
        {
            return new QueryBuilder(_ConType, queryType, tableObject);
        }

        #endregion


        #region [ Get ResultSet of Query ]

        /// <summary>
        /// Returns A DataSet with given Query without any parameter
        /// </summary>
        /// <param name="query">Sql Query</param>
        /// <returns>Returns A DataSet with given Query without any parameter</returns>
        public DataSet GetResultSet(string query)
        {
            try
            {
                Conn.OpenConnection();
                Conn.CreateTransaction();
                DataSet ds = Conn.GetResultSet(query);
                Conn.CommitTransaction();
                return ds;
            }
            catch (Exception exc)
            {
                Conn.RollbackTransaction();
                throw exc;
            }
            finally
            {
                Conn.CloseConnection();
            }
        }

        #endregion


        #region [ Get ResultSet of Query with Parameters ]

        /// <summary>
        /// Returns A DataSet with given Query without any parameter
        /// </summary>
        /// <param name="query">Sql Query</param>
        /// <param name="parameters">hashtable parameters</param>
        /// <returns>Returns A DataSet with given Query without any parameter</returns>
        public DataSet GetResultSet(string query, Hashtable parameters)
        {
            try
            {
                Conn.OpenConnection();
                Conn.CreateTransaction();
                DataSet ds = Conn.GetResultSet(query, parameters);
                Conn.CommitTransaction();
                return ds;
            }
            catch (Exception exc)
            {
                Conn.RollbackTransaction();
                throw exc;
            }
            finally
            {
                Conn.CloseConnection();
            }
        }

        #endregion


        #region [ Execute Query ]

        /// <summary>
        /// Returns execution value of query.
        /// </summary>
        /// <param name="query">Sql Query</param>
        /// <returns>Returns execution value of query.</returns>
        public int ExecuteQuery(string query)
        {
            try
            {
                Conn.OpenConnection();
                Conn.CreateTransaction();
                int retInt = Conn.ExecuteQuery(query);
                Conn.CommitTransaction();
                return retInt;
            }
            catch (Exception exc)
            {
                Conn.RollbackTransaction();
                throw exc;
            }
            finally
            {
                Conn.CloseConnection();
            }
        }

        #endregion


        #region [ Execute Query with Parameters ]

        /// <summary>
        /// Returns execution value of query.
        /// </summary>
        /// <param name="query">Sql Query</param>
        /// <param name="parameters">hashtable contains parameters.</param>
        /// <returns>Returns execution value of query with parameters.</returns>
        public int ExecuteQuery(string query, Hashtable parameters)
        {
            try
            {
                Conn.OpenConnection();
                Conn.CreateTransaction();
                int retInt = Conn.ExecuteQuery(query, parameters);
                Conn.CommitTransaction();
                return retInt;
            }
            catch (Exception exc)
            {
                Conn.RollbackTransaction();
                throw exc;
            }
            finally
            {
                Conn.CloseConnection();
            }
        }

        #endregion


        #region [ Execute Scalar Query ]

        /// <summary>
        /// Returns scalar execution value of query.
        /// </summary>
        /// <param name="query">Sql Query</param>
        /// <returns>Returns scalar execution value of query.</returns>
        public object ExecuteScalar(string query)
        {
            try
            {
                Conn = new Connection(_ConType, _ConnStr);

                Conn.OpenConnection();
                Conn.CreateTransaction();
                object retObj = Conn.ExecuteScalar(query);
                Conn.CommitTransaction();
                return retObj;
            }
            catch (Exception exc)
            {
                Conn.RollbackTransaction();
                throw exc;
            }
            finally
            {
                Conn.CloseConnection();
            }
        }

        #endregion


        #region [ Execute Scalar Query with Parameters ]

        /// <summary>
        /// Returns scalar execution value of query with parameters.
        /// </summary>
        /// <param name="query">Sql Query</param>
        /// <param name="parameters">hashtable contains parameters.</param>
        /// <returns>Returns scalar execution value of query with parameters.</returns>
        public object ExecuteScalar(string query, Hashtable parameters)
        {

            try
            {
                Conn.OpenConnection();
                Conn.CreateTransaction();
                object retObj = Conn.ExecuteScalar(query, parameters);
                Conn.CommitTransaction();
                return retObj;
            }
            catch (Exception exc)
            {
                Conn.RollbackTransaction();
                throw exc;
            }
            finally
            {
                Conn.CloseConnection();
            }
        }

        #endregion


        #region [ Dispose method ]

        /// <summary>
        /// Disposes DbManager object with sub objects.
        /// </summary>
        public void Dispose()
        {
            if (Conn != null)
            {
                Conn.Dispose();
            }
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
